#include "Avalon/Serialization/Serializer.hpp"

using namespace Avalon;
using namespace Avalon::Serialization;
using namespace std;

Serializer::~Serializer() {}

bool Serializer::IsReceiving() const {
  return false;
}

void Serializer::SendNull() {
  int constructorIndex = -1;
  Shuttle("type_id", constructorIndex);
}

void Serializer::SendPointer(const type_info& typeInfo) {
  map<const type_info*, int>::const_iterator constructorIterator =
    m_typeInfoToConstructorIndex.find(&typeInfo);
  int constructorIndex;
  if(constructorIterator == m_typeInfoToConstructorIndex.end()) {
    constructorIndex = static_cast<int>(m_typeInfoToConstructorIndex.size());
    string typeName = GetName(typeInfo);
    m_typeInfoToConstructorIndex.insert(make_pair(&typeInfo, constructorIndex));
    Shuttle("type_id", constructorIndex);
    Shuttle("type_name", typeName);
  } else {
    constructorIndex = constructorIterator->second;
    Shuttle("type_id", constructorIndex);
  }
}

void Serializer::SendSharedPointer(const type_info& typeInfo) {
  map<const type_info*, int>::const_iterator constructorIterator =
    m_typeInfoToSharedConstructorIndex.find(&typeInfo);
  int constructorIndex;
  if(constructorIterator == m_typeInfoToSharedConstructorIndex.end()) {
    constructorIndex = static_cast<int>(
      m_typeInfoToSharedConstructorIndex.size());
    string typeName = GetName(typeInfo);
    m_typeInfoToSharedConstructorIndex.insert(make_pair(&typeInfo,
      constructorIndex));
    Shuttle("type_id", constructorIndex);
    Shuttle("type_name", typeName);
  } else {
    constructorIndex = constructorIterator->second;
    Shuttle("type_id", constructorIndex);
  }
}
